package xyz.lwm.lazycat.beans;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import xyz.lwm.lazycat.annotation.Configuration;
import xyz.lwm.lazycat.utility.It;
import xyz.lwm.lazycat.utility.reflect.Annotations;
import xyz.lwm.lazycat.utility.reflect.ReflectUtil;

/**
 * 配置类加载
 *
 * @author lwm
 * @see xyz.lwm.lazycat.annotation.Import
 */
@Slf4j
@AllArgsConstructor
class BeanDesignImportLoader implements BeanDesignRegistryCustomizer {

    private final Class<?>[] imports;

    private final Annotations annotations;

    private final BeanDesignRegistryCustomizers registryCustomizers;

    @Override
    public void customize(BeanDesignRegistry beanRegistry) {
        It.of(imports).also(clzs -> {
            for (Class<?> clz : clzs) {
                // 判断 import 的类的满足条件
                It<? extends BeanDesign<?>> designIt = BeanDesignUtil.buildDesign(clz);
                // 若该类是 BeanDesignImportRegistrar, 则调用其 importBeanDesigns 方法
                designIt.filter(design ->
                                BeanDesignImportRegistrar.class.isAssignableFrom(design.getType()))
                        .also(design -> {
                            BeanDesignImportRegistrar registrar = (BeanDesignImportRegistrar)
                                    ReflectUtil.newInstance(design.getType());
                            registrar.importBeanDesigns(annotations, beanRegistry);
                        });
                // 若该类不是 BeanDesignImportRegistrar, 则注册该类, 且若该类是配置类, 则继续以配置类的方式注册
                designIt.filter(design ->
                                !BeanDesignImportRegistrar.class.isAssignableFrom(design.getType()))
                        .also(beanRegistry::register)
                        .filter(design ->
                                design.getAnnotations().hasAnnotation(Configuration.class))
                        .also(design ->
                                registryCustomizers.add(new BeanDesignConfigurationLoader(design, registryCustomizers)));
            }
        });
    }


}
